var Random = require('../../utils/random.js');
/*
    Card : 2S means Spade 2

    Card Ranks : 2 3 4 5 6 7 8 9 T J Q K A
                 2 3 4 5 6 7 8 9 10 11 12 13 14
    Card Suits : Spade Heart Club DIOMOND

    Card type: 豹子 {type : 6, value : 10}  "10S 10H 10C"         6 * 14 * 14 * 14 +
               顺金 {type : 5, value : 10}  "10S 9S 8S"
               金花 {type : 4, value : [10, 9, 7]} "10S 9S 7S"
               顺子 {type : 3, value : 10} "10S 9C 8H"
               对子 {type : 2, value : [10, 9]} "10S 10H 9D"
               单张 {type : 1, value : [5, 4, 2]} "5S 4D 2S"
*/
const CARDS = [
    '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', 'TS', 'JS', 'QS', 'KS', 'AS',
    '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', 'TH', 'JH', 'QH', 'KH', 'AH',
    '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', 'TC', 'JC', 'QC', 'KC', 'AC',
    '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', 'TD', 'JD', 'QD', 'KD', 'AD'
];

const HAND_TYPE = {
    BAO_ZI : 6,
    TONG_HUA_SHUN : 5,
    JIN_HUA : 4,
    SHUN_ZI : 3,
    YI_DUI : 2,
    DAN_ZHANG : 1,
};
// HAND_TYPE.BAO_ZI = 6;
// HAND_TYPE.TONG_HUA_SHUN = 5;
// HAND_TYPE.JIN_HUA = 4;
// HAND_TYPE.SHUN_ZI = 3;
// HAND_TYPE.YI_DUI = 2;
// HAND_TYPE.DAN_ZHANG = 1;

const [BASES, BASES_OF_235, BASES_OF_222] = [[14 * 14 * 14, 14 * 14, 14, 1], 3768, 16856];

function getResult(activeHand, passiveHand){
    activeHand = sortHand(activeHand);
    passiveHand = sortHand(passiveHand);
    var activeHandRank = calculateHandRanks(activeHand);
    var passiveHandRank = calculateHandRanks(passiveHand);
    return compareBases(activeHandRank, passiveHandRank);
}

function sortHand(hand) {
    var cards = hand.split(" ");
    cards.sort(function (src, dst) {
        return '__23456789TJQKA'.indexOf(src[0]) - '__23456789TJQKA'.indexOf(dst[0]);
    });

    var ranks = cards.map(card => '__23456789TJQKA'.indexOf(card[0]));

    if (ranks[0] === ranks[1] && ranks[1] === ranks[2]) {
        return hand;
    }

    if (ranks[0] === ranks[1]) {
        return cards[0] + " " + cards[1] + " " + cards[2];
    }

    if (ranks[1] === ranks[2]) {
        return cards[1] + " " + cards[2] + " " + cards[0];
    }

    if (ranks[0] == ranks[2]) {
        return cards[0] + " " + cards[2] + " " + cards[1];
    }

    if (cards[0][0] === '2' && cards[1][0] === '3' && cards[2][0] === 'A') {
        return cards[2] + " " + cards[0] + " " + cards[1];
    }

    if (ranks[0] === ranks[1] - 1 && ranks[1]  === ranks[2] - 1) {
        return cards[0] + " " + cards[1] + " " + cards[2];
    } else {
        return cards[2] + " " + cards[1] + " " + cards[0];
    }
}

function calculateHandRanks(hand) {
    var ranks = [];
    var suites = [];
    var cards = hand.split(" ");
    for (let i = 0; i < cards.length; i++) {
        ranks.push('__23456789TJQKA'.indexOf(cards[i][0]));
        suites.push(cards[i][1]);
    }

    ranks.sort(function (src, dst) {
        return dst - src
    });

    if (ranks[0] === 14 && ranks[1] === 3 && ranks[2] === 2) {
        ranks = [3, 2, 1];
    }

    if (ranks[0] === ranks[1] && ranks[1] === ranks[2]) {
        return 6 * BASES[0] + ranks[0] * BASES[1];
    }

    var isFlush = (suites[0] === suites[1] && suites[1] === suites[2]);
    var isStraight = (ranks[0] === ranks[1] + 1 && ranks[1] === ranks[2] + 1);

    if (isFlush && isStraight) {
        return 5 * BASES[0] + ranks[0] * BASES[1];
    }

    if (isFlush) {
        return 4 * BASES[0] + ranks[0] * BASES[1] + ranks[1] * BASES[2] + ranks[2] * BASES[3];
    }

    if (isStraight) {
        return 3 * BASES[0] + ranks[0] * BASES[1];
    }

    if (ranks[0] === ranks[1] || ranks[1] === ranks[2]) {
        return 2 * BASES[0] + ranks[1] * BASES[1] + (ranks[0] === ranks[1] ? ranks[2] : ranks[0]) * BASES[2];
    }

    return BASES[0] + ranks[0] * BASES[1] + ranks[1] * BASES[2] + ranks[2] * BASES[3];
};

function calculateHandType(hand) {
    var ranks = [];
    var suites = [];
    var cards = hand.split(" ");
    for (let i = 0; i < cards.length; i++) {
        ranks.push('__23456789TJQKA'.indexOf(cards[i][0]));
        suites.push(cards[i][1]);
    }

    ranks.sort(function (src, dst) {
        return dst - src
    });

    if (ranks[0] === 14 && ranks[1] === 3 && ranks[2] === 2) {
        ranks = [3, 2, 1];
    }

    if (ranks[0] === ranks[1] && ranks[1] === ranks[2]) {
        return HAND_TYPE.BAO_ZI;
    }

    var isFlush = (suites[0] === suites[1] && suites[1] === suites[2]);
    var isStraight = (ranks[0] === ranks[1] + 1 && ranks[1] === ranks[2] + 1);

    if (isFlush && isStraight) {
        return HAND_TYPE.TONG_HUA_SHUN;
    }

    if (isFlush) {
        return HAND_TYPE.JIN_HUA;
    }

    if (isStraight) {
        return HAND_TYPE.SHUN_ZI;
    }

    if (ranks[0] === ranks[1] || ranks[1] === ranks[2]) {
        return HAND_TYPE.YI_DUI;
    }

    return HAND_TYPE.DAN_ZHANG;
};

function compareBases(base1, base2) {
    if(base1 >= BASES_OF_222 && base2 == BASES_OF_235) {
        return -1;
    }
    else if(base1 == BASES_OF_235 && base2 >= BASES_OF_222) {
        return 1;
    }
    else if (base1 > base2) {
        return 1;
    }
    return -1;
    /*
    else if (base1 < base2) {
        return -1;
    }
    return 0;
    */
};

function cardsToString(cards) {
    var text = '';
    for (let i = 0; i < cards.length; i++) {
        text += cards[i];
        if (i != cards.length - 1) {
            text += ' ';
        }
    }
    return text;
}

function dealCards(numOfPlayers) {
    var cards = [...CARDS];
    Random.shuffle(cards);
    var result = [];
    for (let i = 0; i < numOfPlayers; i++) {
        result.push(cardsToString(cards.slice(i * 3, (i + 1) * 3)));
    }
    return result;
};

exports.getResult = getResult;
exports.dealCards = dealCards;
exports.calculateHandType = calculateHandType;
exports.sortHand = sortHand;


